package com.tanhua.dubbo.api.mongo;

import com.tanhua.domain.mongo.Option;
import com.tanhua.domain.mongo.Question;
import com.tanhua.domain.mongo.Questionnaire;
import com.tanhua.domain.mongo.UserQuestionnaireStates;
import org.apache.dubbo.config.annotation.Service;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;

import java.util.ArrayList;
import java.util.List;

import com.tanhua.domain.mongo.*;
import com.tanhua.domain.vo.AnswersVo;
import org.springframework.data.mongodb.core.query.Update;


/**
 * @Author:DD
 * @Date :2021/10/6 12:15
 */
@Service
public class TestSoulImpl implements TestSoulApi {
    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 根据用户提交的问题的选项，计算出用户四个维度的累积得分，封装到报告对象中返回待进行进一步处理
     *
     * @param answerVos
     * @return
     */
    @Override
    public Report findScore(List<AnswersVo> answerVos) {
        double abstractScore = 0;
        double extrovertedScore = 0;
        double judgmentScore = 0;
        double rationalScore = 0;
        // 遍历集合
        for (AnswersVo answerVo : answerVos) {
            String optionId = answerVo.getOptionId();
            Query query = new Query();
            query.addCriteria(Criteria.where("id").is(optionId));
            Option option = mongoTemplate.findOne(query, Option.class);
            if (option == null) {
                continue;
            }
            abstractScore += option.getAbstractScore();
            extrovertedScore += option.getExtrovertedScore();
            judgmentScore += option.getJudgmentScore();
            rationalScore += option.getRationalScore();
        }
        Report report = new Report();
        report.setAbstractScore((int) abstractScore);
        report.setExtrovertedScore((int) extrovertedScore);
        report.setJudgmentScore((int) judgmentScore);
        report.setRationalScore((int) rationalScore);
        return report;
    }

    /**
     * 通过用户提交问卷得出的结果。判断并查询出用户的鉴定结果
     *
     * @param score
     * @return
     */
    @Override
    public Conclusion findConclusion(double score) {
        Query query = new Query();
        query.addCriteria(Criteria.where("lowerLimit").lte(score).and("upperLimit").gt(score));
        return mongoTemplate.findOne(query, Conclusion.class);
    }

    /**
     * 保存用户问卷报告
     *
     * @param report
     * @param questionId
     */
    @Override
    public void saveReport(Report report, Long userId, String questionId) {
        Integer star = getStart(questionId);
        report.setType(star);
        Query queryReport = new Query(Criteria.where("userId").is(userId).and("type").is(star));
        Report oldReport = mongoTemplate.findOne(queryReport, Report.class);
        //根据问题Id查出问卷星级
        //如果已经有报告表了，则进行删除
        if (oldReport != null) {
            mongoTemplate.remove(oldReport);
        }
        //保存最新数据
        mongoTemplate.save(report);
    }


    /**
     * 当用户提交当前问卷后，解锁下一等级的问卷
     *
     * @param questionId
     * @param userId
     */
    @Override
    public void unlockNextQuestionnaire(String questionId, Long userId) {
        Integer star = getStart(questionId);
        //通过判断星级，解锁下一星级的问卷。在查询问卷列表的时候会在这UserQuestionnaireStates中获取当前用户问卷状态
        //判断当前用户所做的问卷如果是初级问卷，则将数据库中的中级问卷的状态改成解锁状态
        if (star == 2) {
            Update update = new Update();
            Query query = new Query(Criteria.where("userId").is(userId));
            update.set("middleStatus", 0);
            mongoTemplate.updateFirst(query, update, UserQuestionnaireStates.class);
        }
        //判断当前用户所做的问卷如果是中级问卷，则将数据库中的高级问卷的状态改成解锁状态
        if (star == 3) {
            Update update = new Update();
            Query query = new Query(Criteria.where("userId").is(userId));
            update.set("highStatus", 0);
            mongoTemplate.updateFirst(query, update, UserQuestionnaireStates.class);
        }
        // 若当前用户做的是高级问卷则没有需要解锁的问卷了，不做任何处理
    }

    private Integer getStart(String questionId) {
        //通过questionId查找问卷id
        Query queryQuestion = new Query();
        queryQuestion.addCriteria(Criteria.where("id").is(questionId));
        Question question = mongoTemplate.findOne(queryQuestion, Question.class);
        String questionnaireId = question.getQuestionnaireId().toHexString();
        //通过问卷Id查出答题的星级
        Query queryQuestionnaire = new Query();
        queryQuestionnaire.addCriteria(Criteria.where("id").is(questionnaireId));
        Questionnaire questionnaire = mongoTemplate.findOne(queryQuestionnaire, Questionnaire.class);
        return questionnaire.getStar();
    }

    /**
     * 通过当前用户userId与当前试卷等级，查询对应等级的报告id
     * @param userId
     * @param star
     * @return
     */
    @Override
    public String getReportId(Long userId, Integer star) {
        Query queryReportId = new Query(Criteria.where("userId").is(userId).and("type").is(star));
        Report report = mongoTemplate.findOne(queryReportId, Report.class);
        if(report!=null){
            ObjectId reportId = report.getId();
            return reportId.toHexString();
        }
        return null;
    }


    /**
     * 根据用户ID从userquestionnairestatus获取初级,中级,高级的锁定解锁状态
     *
     * @param userId
     * @return
     */
    @Override
    public UserQuestionnaireStates getQuestionnaireStatus(Long userId) {
        Query query = new Query();
        query.addCriteria(Criteria.where("userId").is(userId));
        return mongoTemplate.findOne(query, UserQuestionnaireStates.class);
    }

    /**
     * 获取所有的调查问卷表的数据
     *
     * @return
     */
    @Override
    public List<Questionnaire> findAllQuestionnaire() {
        return mongoTemplate.find(new Query(), Questionnaire.class);
    }

    /**
     * 根据调查问卷表的发布id去问题表获取其问题数据
     *
     * @param Id
     * @return
     */
    @Override
    public List<Question> findQuestionById(ObjectId Id) {
        Query query = new Query();
        query.addCriteria(Criteria.where("questionnaireId").is(Id));
        return mongoTemplate.find(query, Question.class);
    }

    /**
     * 根据问题发布id去option表去获取选项数据
     *
     * @param id
     * @return
     */
    @Override
    public List<Option> findOption(ObjectId id) {
        Query query = new Query();
        query.addCriteria(Criteria.where("questionId").is(id));
        return mongoTemplate.find(query, Option.class);
    }


//*********************************************************************************

    /**
     * @Description: 根据id 从鉴定表中查询维度值
     * @Param:
     * @return:
     **/
    @Override
    public Report findReportById(String id) {
        Query query = new Query();
        query.addCriteria(Criteria.where("id").is(id));

        return mongoTemplate.findOne(query, Report.class);
    }

    /**
     * @Description: 根据conclusionId，查询根据conclusion对应的信息
     * @Param:
     * @return:
     **/
    @Override
    public Conclusion findConclusionById(Object conclusionId) {

        Query query = new Query();
        query.addCriteria(Criteria.where("id").is(conclusionId));

        return mongoTemplate.findOne(query, Conclusion.class);

    }

    /**
     * @Description: 遍历查询conclusion表，获取conclusionId相同的userId放入到集合中
     * @Param:
     * @return:
     **/
    @Override
    public List<Long> findSimilarYou(Object conclusionId, Long userId) {

        //当前用户id
        Query query = new Query();
        query.addCriteria(Criteria.where("conclusionId").is(conclusionId).and("userId").ne(userId));

        List<Long> userIds = new ArrayList<>();
        List<Report> reports = mongoTemplate.find(query, Report.class);
        for (Report report : reports) {
            if (report.getUserId() != (userId)) {
                userIds.add(report.getUserId());
            }
        }

        return userIds;
    }
}
